package fr.umlv.galcon.game;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import fr.umlv.galcon.item.ItemListSingleton;
import fr.umlv.galcon.player.Player;
import fr.umlv.galcon.ship.ShipAbstract;

/**
 * Check the state of the Game.
 * 
 */
public class GalconManager {
    private static boolean gameOver = false;
    private static HashMap<Player, Integer> playersArray = new HashMap<Player, Integer>();
    private static double scroll = 50;

    /**
     * Add a player to the list of players. This method should be called when a
     * player is created.
     * 
     * @param player
     *            The player to add.
     * @param value
     *            The number of planet the player owns.
     */
    public static void addPlayer(Player player, int value) {
	playersArray.put(player, value);
    }

    /**
     * Return if the game is over. This method is based on the boolean "endGame"
     * and also on the fact that only one player should have more than zero
     * planet to set the end of the game.
     * 
     * @return true if the game is end else false
     */
    public static boolean getEndGame() {
	if (gameOver == true)
	    return true;

	if (playersArray.size() > 0) {
	    Player player;
	    Player potentialWinner = null;
	    Set<Player> entries = playersArray.keySet();
	    Iterator<Player> it = entries.iterator();
	    int playing = 0;
	    while (it.hasNext()) {
		player = it.next();
		if (playersArray.get(player) != 0) {
		    playing++;
		    potentialWinner = player;
		}
	    }

	    int size = ItemListSingleton.getInstance().getShipList().size();
	    for (int i = 0; i < size; i++) {
		synchronized (ItemListSingleton.getInstance().getShipList()) {
		    ShipAbstract ship = ItemListSingleton.getInstance().getShipList().get(i);
		    if (ship != null && !ship.getSquadron().getOwner().equals(potentialWinner))
			return false;
		}

	    }
	    if (playing > 1)
		return false;
	    return true;
	}
	return true;
    }

    /**
     * Return a map which contains all the players and the quantity of planet
     * each owns.
     * 
     * @return The map of players.
     */
    public static Map<Player, Integer> getPlayers() {
	return playersArray;
    }

    /**
     * Get the value of the scrolling item.
     * 
     * @return The percentage of Ship to send.
     */
    public static double getScroll() {
	return scroll;
    }

    /**
     * Get the winner of the game.
     * 
     * @return The player who won the game.
     */
    public static Player getWinner() {
	Player player;
	Set<Player> entries = playersArray.keySet();
	Iterator<Player> it = entries.iterator();
	while (it.hasNext()) {
	    player = it.next();
	    if (playersArray.get(player) != 0)
		return player;
	}
	return null;
    }

    /**
     * Get the state of the game, if is over or not. Only based on the value
     * "endGame".
     * 
     * @return A boolean which informs if the game is over or not.
     */
    public static boolean isOver() {
	return gameOver;
    }

    /**
     * Raise the scrolling value.
     */
    public static void raiseScroll() {
	if (scroll <= 95)
	    scroll += 5;
    }

    /**
     * Reduce the scrolling value.
     */
    public static void reduceScroll() {
	if (scroll >= 10)
	    scroll -= 5;
    }

    /**
     * Set the end of the game.
     * 
     * @param value
     *            A boolean.
     */
    public static void setGameOver(boolean value) {
	gameOver = value;
    }
}
